﻿using CKS.Core.Framework;
using FreeSql;
using ImportPlcPointPosition.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Models.ProductionControl;
using static FreeSql.Internal.GlobalFilter;

namespace CKS.PLC.Action.System
{
    public class StartWorkingAction : PLCAction
    {
        /// <summary>
        /// 加工请求信号：开始加工，
        /// 验证是否允许加工
        /// </summary>
        /// <param name="_value"></param>
        public StartWorkingAction(DecodeValue _value) : base(_value)
        {
        }

        /*
           回复信号 1：允许加工 2不允许加工
         */
        public override void Execute()
        {
            var result = Value.Value.ToInt();
           
               
            var P = Value.Position;
            var act = conn.Select<CksPlcActions>().Where(a => a.ActionType == 2 && a.PlcId == P.PlcId && a.ActionId == P.ActionId)
                .First();
            if(act == null)
            {
                throw new Exception($"加工请求信号未配置此动作编号PLC:{P.PlcId},DB:{P.BlockDb},Action:{P.ActionId}");
            }
            var replyPos = Value.GetPosition(act.WriteDB, act.ActionId);
            if (result == 1)
            {
                //查询工艺节点
                var technical = conn.Select<CksTechnicalFlowNodes>().Where(a => a.Id == act.BusinessId).First();
                    
                var prevTechNode = conn.Select<CksTechnicalFlowNodes>().Where(a => a.NodeId == technical.PreNodeId).First();

                var fields = conn.Select<CksValidationField>()
                    .Where(a => a.BusinessType == 1 && a.BusinessId == act.BusinessId).OrderBy(a => a.Sequence)
                    .ToList();

                //验证前置节点
                short ErrCode = 0;
                string ErrMessge = "";
                var codeField = fields.Find(a => a.IsPrimary);
                if(codeField == null)
                    throw new Exception($"加工请求信号未配置条码验证字段;PLC:{P.PlcId},DB:{P.BlockDb},Action:{P.ActionId}");


                var codevalue = Value.GetLinkData(codeField.DataId);
                if (technical == null || technical.Nullity)
                {
                    //工艺路线未配置，或者当前节点是禁用状态，直接回复信号OK
                    WriteInt16(replyPos, 1);
                    EventBus.AddLog($"模块：开始加工；工站：{SiemensClient.PlcInfo.WorkstationCode};{codevalue};已允许");
                    return;
                }

                short rejectCode = 2; //如果验证失败，写入2拒绝加工（可根据项目实际情况写入错误码方便HMI显示错误信息）
                //需要验证前置节点并且前置节点未被禁用
                if (technical.NeedPrevCheck && prevTechNode !=null && !prevTechNode.Nullity)
                {
                    ErrCode= ValidNode(prevTechNode,true,out ErrMessge);
                    if (ErrCode != 0)
                    {
                        WriteInt16(replyPos, rejectCode);
                        EventBus.AddLog($"模块：开始加工；工站：{SiemensClient.PlcInfo.WorkstationCode};{codevalue};{ErrMessge}");
                        return;
                    }
                } 
                ErrCode = ValidNode(technical, false, out ErrMessge);
                if (ErrCode != 0)
                {
                    WriteInt16(replyPos, rejectCode);
                    EventBus.AddLog($"模块：开始加工；工站：{SiemensClient.PlcInfo.WorkstationCode};{codevalue};{ErrMessge}");
                    return;
                }
                WriteInt16(replyPos, 1);
                EventBus.AddLog($"模块：开始加工；工站：{SiemensClient.PlcInfo.WorkstationCode};{codevalue};验证通过-已允许加工");

            }
            else if (result == 0)
            {
                //复位上位机的信号
                WriteInt16(replyPos, 0);
                EventBus.AddLog($"模块：开始加工；工站：{SiemensClient.PlcInfo.WorkstationCode};重置");

            }
            
                

        }

        private short ValidNode(CksTechnicalFlowNodes technical, bool IsPrev, out string errMessge)
        {
            errMessge = "";
            var fields = conn.Select<CksValidationField>()
                       .Where(a => a.BusinessType == 1 && a.BusinessId == technical.Id).OrderBy(a => a.Sequence)
                       .ToList();
            var errcode = 0;
          
            if(technical.Nullity)
            {
                //无论是前置节点还是当前节点，禁用就不进行验证
                return 0;
            }


            foreach (var item in fields)
            {
                var data = Value.GetLinkData(item.DataId);
                var suffix = GetSuffix(data.ToString());
                
                if (item.IsPrimary) //是条码字段
                {
                    var results = conn.Select<CksCollected>()
                    .Where(a => a.TableId == technical.TableId && a.Suffix_4 == suffix && a.PrimaryCode == data.ToString())
                    .OrderByDescending(a=>a.CreatedTime) .ToList(); //查询加工记录
                    if (!technical.AllowReprocess)//不允许重复加工，查询当前站是否存在该条码
                    {
                        
                        if (IsPrev) //当前是前置节点，前置记录不能为空
                        { 
                            if(results.Count==0)
                            {
                                errcode = 2;
                                errMessge = "不允许跳工站加工";
                                break;
                            }
                        }
                        else
                        {
                            //当前节点，则验证不可以重复
                            if(results.Count > 0)
                            {
                                errcode = 3;
                                errMessge = "不允许重复加工";
                                break;
                            }
                        }
                    }

                    if (!technical.AllowOkReprocess && !IsPrev) // 不允许OK件重复加工
                    {
                        if (results.FindAll(a=>a.Result == 1).Count > 0)
                        {
                            errcode = 4;
                            errMessge = "不允许OK件重复加工";
                            break;
                        }
                    }

                    if(technical.RequireOk && IsPrev)
                    {
                        if(results.First().Result !=1)
                        {
                            errcode = 5;
                            errMessge = "上工站加工失败";
                            break;
                        }
                    }

                }
            }


            return (short)errcode;
        }
    }
}
